package com.gbb.simple.utils;

import java.lang.Thread.UncaughtExceptionHandler;

import android.content.Context;
import android.os.Looper;
import android.widget.Toast;

import com.gbb.common.utils.AppManager;
import com.gbb.common.utils.LogUtil;

/**
 * 应用全局异常捕获处理
 */
public class GlobalExceptionHandler implements UncaughtExceptionHandler {

    private Thread.UncaughtExceptionHandler mDefaultHandler;
    private static GlobalExceptionHandler INSTANCE = new GlobalExceptionHandler();
    private Context mContext;

    private GlobalExceptionHandler(){
    }

    public static GlobalExceptionHandler getInstance(){
        return INSTANCE;
    }

    /**
     * 初始化
     *
     * @param context
     */
    public void init(Context context){
        mContext = context;
        // 获取系统默认的UncaughtException处理器
        mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();
        Thread.setDefaultUncaughtExceptionHandler(this);
    }

    /**
     * 当UncaughtException发生时会转入该函数来处理
     */
    @Override
    public void uncaughtException(Thread thread,Throwable ex){
        if(!handleException(ex) && mDefaultHandler != null) {
            // 如果没有处理则让系统默认的异常处理器来处理
            mDefaultHandler.uncaughtException(thread,ex);
        } else {
            try {
                Thread.sleep(2000);
            } catch(InterruptedException e) {
                LogUtil.writeLog(e);
            }
            AppManager.getInstance().exitSystem();
            // 退出程序
            android.os.Process.killProcess(android.os.Process.myPid());
            System.exit(1);
        }
    }

    private boolean handleException(Throwable ex){
        if(ex == null) {
            return true;
        }
        // 使用Toast来显示异常信息
        LogUtil.writeLog("以下异常信息导致程序崩溃:\n");
        LogUtil.writeLog(ex);
        new Thread() {

            @Override
            public void run(){
                Looper.prepare();
                Toast.makeText(mContext,"很抱歉,程序出现异常.将在2秒后关闭。",Toast.LENGTH_LONG).show();
                Looper.loop();
            }
        }.start();
        return true;
    }
    
}
